package com.ysstech.kettle.service.impl;

import com.alibaba.druid.stat.TableStat;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ysstech.common.util.DateUtil;
import com.ysstech.common.util.JdbcUtil;
import com.ysstech.kettle.entity.JobRelation;
import com.ysstech.kettle.entity.JobTask;
import com.ysstech.kettle.entity.JobTaskDetails;
import com.ysstech.kettle.init.KettleConfig;
import com.ysstech.kettle.mapper.JobRelationMapper;
import com.ysstech.kettle.service.JobRelationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ysstech.kettle.service.JobTaskDetailsService;
import com.ysstech.kettle.service.JobTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 任务关联关系表 服务实现类
 * </p>
 *
 * @author lishuangliang
 * @since 2022-10-23
 */
@Slf4j
@Service
public class JobRelationServiceImpl extends ServiceImpl<JobRelationMapper, JobRelation> implements JobRelationService {


    @Autowired
    private JobRelationMapper jobRelationMapper;
    @Autowired
    private JobTaskDetailsService jobTaskDetailsService;
    @Autowired
    private KettleConfig kettleConfig;

    /**
     * 获取所有执行任务中的 新的依赖关系
     *
     * @param ids 任务id
     * @return
     */
    public Map<String, List<String>> queryRelation(List<String> ids) throws Exception {
        // 需要等待的数据
        Map<String, List<String>> mapRelation = new HashMap<>();
        // 查询依赖关系
        QueryWrapper<JobRelation> wrapper = new QueryWrapper<>();
        wrapper.in("TASK_ID", ids);
        List<JobRelation> jobRelations = jobRelationMapper.queryJobRelation(wrapper);
        if (CollectionUtils.isEmpty(jobRelations)) {
            return mapRelation;
        }
        Map<String, List<String>> map = new HashMap<>();
        for (JobRelation jobRelation : jobRelations) {
            if (null == jobRelation && CollectionUtils.isEmpty(jobRelation.getListRelation())) {
                continue;
            }
            List<String> list = new ArrayList<>();
            for (JobRelation relation : jobRelation.getListRelation()) {
                list.add(relation.getRelationTaskId());
            }
            map.put(jobRelation.getTaskId(), list);
        }
        //一次执行的所有任务，如果存在依赖关系，就需要等有依赖关系的执行完成之后在执行
        Map<String, String> mapTaskId = new HashMap<>();
        for (String taskId : ids) {
            mapTaskId.put(taskId, taskId);
        }
        for (String taskId : ids) {
            if (!map.containsKey(taskId)) {  //有依赖的id
                continue;
            }
            // 依赖的关系的所有编号
            List<String> listRelation = map.get(taskId);
            // 按照当前执行的所有编号 新的依赖关系
            List<String> newListRelation = new ArrayList<>();
            for (String str : listRelation) {
                if (mapTaskId.containsKey(str)) {
                    newListRelation.add(str);
                    continue;
                }
            }
            mapRelation.put(taskId, newListRelation);
        }
        return mapRelation;
    }


    /**
     * 保存任务的对应关系
     *
     * @throws Exception
     */
    public void insertJobRelation(JobTask jobTask) throws Exception {
        if (null == jobTask || StringUtils.isBlank(jobTask.getId())) {
            log.info("没有获取到任务信息");
            return;
        }
        // 行删除改任务的所有依赖关系
        QueryWrapper<JobRelation> wrapperRelation = new QueryWrapper<>();
        wrapperRelation.eq("TASK_ID", jobTask.getId());
        this.remove(wrapperRelation);
        // 获取任务的所有明细任务
        List<JobTaskDetails> jobTaskDetailsList = jobTaskDetailsService.listInfo(jobTask.getId());
        if (CollectionUtils.isEmpty(jobTaskDetailsList)) {
            log.info(jobTask.getName() + "该任务没有明细任务信息");
            return;
        }
        // 语句中说依赖的表
        List<String> list = new ArrayList<>();
        for (JobTaskDetails details : jobTaskDetailsList) {
            // 只取了输入输出的
            if (null == details || StringUtils.isBlank(details.getInputSql()) || !"1".equals(details.getFtype())) {
                continue;
            }
            // 在查找所用到的表，解析sql
            Map<TableStat.Name, TableStat> map = JdbcUtil.getSqlTableInfoMap(details.getInputSql(), kettleConfig.type.toLowerCase());
            if (CollectionUtils.isEmpty(map)) {
                continue;
            }
            for (Map.Entry<TableStat.Name, TableStat> entry : map.entrySet()) {
                String tableName = entry.getKey().getName();
                if (StringUtils.isBlank(tableName)) {
                    continue;
                }
                list.add(tableName);
            }
        }
        if (CollectionUtils.isEmpty(list)) {
            log.info(jobTask.getName() + "该任务没有输入表信息！");
            return;
        }
        // 查询表所用到表所在的任务 ,不包含自己任务的
        QueryWrapper<JobTaskDetails> wrapper = new QueryWrapper<>();
        wrapper.in("OUTPUT_TABLE", list);
        wrapper.ne("TASK_ID", jobTask.getId());
        List<JobTaskDetails> taskDetails = jobTaskDetailsService.list(wrapper);
        if (CollectionUtils.isEmpty(taskDetails)) {
            log.info(jobTask.getName() + "该任务对应的关联关系！");
            return;
        }
        List<JobRelation> jobRelations = new ArrayList<>();
        for (JobTaskDetails jobTaskDetails : taskDetails) {
            JobRelation jobRelation = new JobRelation();
            jobRelation.setId(DateUtil.generateUUID());
            jobRelation.setStatus(1);
            jobRelation.setTaskId(jobTask.getId());
            jobRelation.setRelationTaskId(jobTaskDetails.getTaskId());
            jobRelations.add(jobRelation);
        }
        this.saveBatch(jobRelations);
    }

}
